//! 用户自定义模块
//! 
//! 提供用户自定义数据生成规则和格式的支持，满足个性化需求

use std::collections::HashMap;
use serde_json::Value;
use crate::error::{DataForgeError, Result};

pub mod api;
pub mod plugins;

pub use api::*;
pub use plugins::*;

/// 自定义生成器特征
pub trait CustomGenerator: Send + Sync {
    /// 生成器名称
    fn name(&self) -> &str;
    
    /// 生成器描述
    fn description(&self) -> &str;
    
    /// 生成数据
    fn generate(&self) -> Result<Value>;
    
    /// 生成带参数的数据
    fn generate_with_params(&self, params: &HashMap<String, Value>) -> Result<Value> {
        // 默认实现忽略参数
        let _ = params;
        self.generate()
    }
    
    /// 验证参数
    fn validate_params(&self, params: &HashMap<String, Value>) -> Result<()> {
        // 默认实现不验证参数
        let _ = params;
        Ok(())
    }
    
    /// 获取参数模式
    fn param_schema(&self) -> HashMap<String, ParamType> {
        HashMap::new()
    }
}

/// 参数类型
#[derive(Debug, Clone, PartialEq)]
pub enum ParamType {
    String { max_length: Option<usize> },
    Integer { min: Option<i64>, max: Option<i64> },
    Float { min: Option<f64>, max: Option<f64> },
    Boolean,
    Array(Box<ParamType>),
    Object(HashMap<String, ParamType>),
}

/// 自定义生成器注册表
pub struct CustomGeneratorRegistry {
    generators: HashMap<String, Box<dyn CustomGenerator>>,
}

impl CustomGeneratorRegistry {
    /// 创建新的注册表
    pub fn new() -> Self {
        Self {
            generators: HashMap::new(),
        }
    }

    /// 注册生成器
    pub fn register<G>(&mut self, generator: G) -> Result<()>
    where
        G: CustomGenerator + 'static,
    {
        let name = generator.name().to_string();
        
        if self.generators.contains_key(&name) {
            return Err(DataForgeError::validation(&format!(
                "Generator '{}' is already registered", name
            )));
        }
        
        self.generators.insert(name, Box::new(generator));
        Ok(())
    }

    /// 获取生成器
    pub fn get(&self, name: &str) -> Option<&dyn CustomGenerator> {
        self.generators.get(name).map(|g| g.as_ref())
    }

    /// 移除生成器
    pub fn unregister(&mut self, name: &str) -> bool {
        self.generators.remove(name).is_some()
    }

    /// 列出所有生成器
    pub fn list_generators(&self) -> Vec<GeneratorInfo> {
        self.generators.iter().map(|(name, generator)| {
            GeneratorInfo {
                name: name.clone(),
                description: generator.description().to_string(),
                param_schema: generator.param_schema(),
            }
        }).collect()
    }

    /// 生成数据
    pub fn generate(&self, name: &str, params: Option<&HashMap<String, Value>>) -> Result<Value> {
        let generator = self.generators.get(name)
            .ok_or_else(|| DataForgeError::validation(&format!("Generator '{}' not found", name)))?;

        if let Some(params) = params {
            generator.validate_params(params)?;
            generator.generate_with_params(params)
        } else {
            generator.generate()
        }
    }

    /// 获取生成器数量
    pub fn count(&self) -> usize {
        self.generators.len()
    }
}

impl Default for CustomGeneratorRegistry {
    fn default() -> Self {
        Self::new()
    }
}

/// 生成器信息
#[derive(Debug, Clone)]
pub struct GeneratorInfo {
    pub name: String,
    pub description: String,
    pub param_schema: HashMap<String, ParamType>,
}

/// 内置自定义生成器示例
pub struct RandomStringGenerator {
    name: String,
}

impl RandomStringGenerator {
    pub fn new() -> Self {
        Self {
            name: "random_string".to_string(),
        }
    }
}

impl CustomGenerator for RandomStringGenerator {
    fn name(&self) -> &str {
        &self.name
    }

    fn description(&self) -> &str {
        "Generates random strings with configurable length and character set"
    }

    fn generate(&self) -> Result<Value> {
        use rand::Rng;
        let mut rng = rand::thread_rng();
        let length = rng.gen_range(5..=20);
        let chars: Vec<char> = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".chars().collect();
        
        let random_string: String = (0..length)
            .map(|_| chars[rng.gen_range(0..chars.len())])
            .collect();
            
        Ok(Value::String(random_string))
    }

    fn generate_with_params(&self, params: &HashMap<String, Value>) -> Result<Value> {
        use rand::Rng;
        let mut rng = rand::thread_rng();
        
        let length = params.get("length")
            .and_then(|v| v.as_u64())
            .unwrap_or(10) as usize;
            
        let charset = params.get("charset")
            .and_then(|v| v.as_str())
            .unwrap_or("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
            
        let chars: Vec<char> = charset.chars().collect();
        if chars.is_empty() {
            return Err(DataForgeError::validation("Character set cannot be empty"));
        }
        
        let random_string: String = (0..length)
            .map(|_| chars[rng.gen_range(0..chars.len())])
            .collect();
            
        Ok(Value::String(random_string))
    }

    fn validate_params(&self, params: &HashMap<String, Value>) -> Result<()> {
        if let Some(length) = params.get("length") {
            if let Some(len) = length.as_u64() {
                if len == 0 || len > 1000 {
                    return Err(DataForgeError::validation("Length must be between 1 and 1000"));
                }
            } else {
                return Err(DataForgeError::validation("Length must be a positive integer"));
            }
        }
        
        if let Some(charset) = params.get("charset") {
            if let Some(cs) = charset.as_str() {
                if cs.is_empty() {
                    return Err(DataForgeError::validation("Character set cannot be empty"));
                }
            } else {
                return Err(DataForgeError::validation("Character set must be a string"));
            }
        }
        
        Ok(())
    }

    fn param_schema(&self) -> HashMap<String, ParamType> {
        let mut schema = HashMap::new();
        schema.insert("length".to_string(), ParamType::Integer { min: Some(1), max: Some(1000) });
        schema.insert("charset".to_string(), ParamType::String { max_length: None });
        schema
    }
}

impl Default for RandomStringGenerator {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_custom_generator_registry() {
        let mut registry = CustomGeneratorRegistry::new();
        let generator = RandomStringGenerator::new();
        
        assert!(registry.register(generator).is_ok());
        assert_eq!(registry.count(), 1);
        
        let result = registry.generate("random_string", None);
        assert!(result.is_ok());
        
        if let Ok(Value::String(s)) = result {
            assert!(!s.is_empty());
        } else {
            panic!("Expected string value");
        }
    }

    #[test]
    fn test_random_string_generator() {
        let generator = RandomStringGenerator::new();
        
        assert_eq!(generator.name(), "random_string");
        assert!(!generator.description().is_empty());
        
        let result = generator.generate();
        assert!(result.is_ok());
        
        if let Ok(Value::String(s)) = result {
            assert!(s.len() >= 5 && s.len() <= 20);
        }
    }

    #[test]
    fn test_random_string_generator_with_params() {
        let generator = RandomStringGenerator::new();
        let mut params = HashMap::new();
        params.insert("length".to_string(), Value::Number(serde_json::Number::from(5)));
        params.insert("charset".to_string(), Value::String("abc".to_string()));
        
        assert!(generator.validate_params(&params).is_ok());
        
        let result = generator.generate_with_params(&params);
        assert!(result.is_ok());
        
        if let Ok(Value::String(s)) = result {
            assert_eq!(s.len(), 5);
            assert!(s.chars().all(|c| "abc".contains(c)));
        }
    }

    #[test]
    fn test_invalid_params() {
        let generator = RandomStringGenerator::new();
        let mut params = HashMap::new();
        params.insert("length".to_string(), Value::Number(serde_json::Number::from(0)));
        
        assert!(generator.validate_params(&params).is_err());
        
        params.insert("length".to_string(), Value::Number(serde_json::Number::from(2000)));
        assert!(generator.validate_params(&params).is_err());
        
        params.insert("charset".to_string(), Value::String("".to_string()));
        assert!(generator.validate_params(&params).is_err());
    }

    #[test]
    fn test_duplicate_registration() {
        let mut registry = CustomGeneratorRegistry::new();
        let generator1 = RandomStringGenerator::new();
        let generator2 = RandomStringGenerator::new();
        
        assert!(registry.register(generator1).is_ok());
        assert!(registry.register(generator2).is_err());
    }

    #[test]
    fn test_list_generators() {
        let mut registry = CustomGeneratorRegistry::new();
        let generator = RandomStringGenerator::new();
        
        registry.register(generator).unwrap();
        
        let generators = registry.list_generators();
        assert_eq!(generators.len(), 1);
        assert_eq!(generators[0].name, "random_string");
        assert!(!generators[0].description.is_empty());
        assert!(!generators[0].param_schema.is_empty());
    }
}